package org.tis.tools.senior.module.developer.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.tis.tools.senior.module.developer.controller.request.*;
import org.tis.tools.senior.module.developer.dao.SDeliveryMapper;
import org.tis.tools.senior.module.developer.entity.*;
import org.tis.tools.senior.module.developer.entity.enums.*;
import org.tis.tools.senior.module.developer.entity.vo.*;
import org.tis.tools.senior.module.developer.exception.DeveloperException;
import org.tis.tools.senior.module.developer.service.*;
import org.tis.tools.senior.module.developer.util.DeveloperUtils;
import org.tmatesoft.svn.core.SVNException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * sDelivery的Service接口实现类
 *
 * @author Auto Generate Tools
 * @date 2018/06/20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SDeliveryServiceImpl extends ServiceImpl<SDeliveryMapper, SDelivery> implements ISDeliveryService {

    @Autowired
    private ISBranchMappingService branchMappingService;
    @Autowired
    private ISBranchService branchService;
    @Autowired
    private ISWorkitemService workitemService;
    @Autowired
    private ISDeliveryListService deliveryListService;
    @Autowired
    private ISProjectService projectService;
    @Autowired
    private ISCheckService checkService;
    @Autowired
    private ISProfilesService profilesService;
    @Autowired
    private ISStandardListService standardListService;
    @Autowired
    private ISSvnKitService svnKitService;
    @Autowired
    private ISMergeReportService mergeReportService;
    @Autowired
    private ISMergeReportListService mergeReportListService;

    @Override
    public Page<DeliveryWorkitemDetail> getDeliveryAll(Page<DeliveryWorkitemDetail> page,
                                         EntityWrapper<DeliveryWorkitemDetail> wrapper, SSvnAccount svnAccount) {

        EntityWrapper<SWorkitem> workitemEntityWrapper = new EntityWrapper<>();
        workitemEntityWrapper.eq(SWorkitem.COLUMN_OWNER, svnAccount.getUserId());
        List<SWorkitem> workitems = workitemService.selectList(workitemEntityWrapper);

        List<Integer> guidWorkitems = workitems.stream().map(SWorkitem::getGuid).collect(Collectors.toList());

        if(!svnAccount.getRole().equals(SvnRole.RCT)){
            if(guidWorkitems.size() > 0){
                wrapper.in(SDelivery.COLUMN_GUID_WORKITEM, guidWorkitems);
            }else{
                return new Page<DeliveryWorkitemDetail>();
            }
        }
        return page.setRecords(this.baseMapper.selectDeliveryWorkitemDetail(page, wrapper));
    }

    @Override
    public DeliveryDetail getMergeInfo(MergeDeliveryRequest mergeDelivery, String userId) {
        List<SDelivery> deliveryList = isAllowMerge(mergeDelivery.getMergeList());
        // 获取对应工作项信息
        List<String> workitemGuids = deliveryList.stream()
                .map(SDelivery::getGuidWorkitem).map(String::valueOf).collect(Collectors.toList());
        EntityWrapper<SWorkitem> workitemWrapper = new EntityWrapper<>();
        workitemWrapper.in(SWorkitem.COLUMN_GUID, workitemGuids);
        List<SWorkitem> sWorkitems = workitemService.selectList(workitemWrapper);
        // 获取分支信息
        EntityWrapper<SBranchMapping> branchMappingWrapper = new EntityWrapper<>();
        branchMappingWrapper.eq(SBranchMapping.COLUMN_FOR_WHAT, BranchForWhat.WORKITEM.getValue());
        branchMappingWrapper.in(SBranchMapping.COLUMN_GUID_OF_WHATS, workitemGuids);
        List<String> branchGuids = branchMappingService.selectList(branchMappingWrapper).stream()
                .map(SBranchMapping::getGuidBranch).map(Object::toString).collect(Collectors.toList());
        EntityWrapper<SBranch> branchWrapper = new EntityWrapper<>();
        branchWrapper.in(SBranch.COLUMN_GUID, branchGuids);
        List<SBranch> sBranches = branchService.selectList(branchWrapper);

        // 获取清单详情
        EntityWrapper<SDeliveryList> deliveryListWrapper = new EntityWrapper<>();
        deliveryListWrapper.in(SDeliveryList.COLUMN_GUID_DELIVERY, mergeDelivery.getMergeList());
        List<SDeliveryList> sDeliveryLists = deliveryListService.selectList(deliveryListWrapper);
        List<DeliveryProjectDetail> details = DeliveryProjectDetail.getDeliveryListDetail(
                            sDeliveryLists,projectService.selectProjectAll());
        // 统计投放消息
        // 补丁类型
        Map<String, Integer> patchCount = new HashMap<>(5);
        details.forEach(d -> d.getPatchType().forEach(p -> {
            patchCount.merge(p, 1, (a, b) -> a + b);
        }));

        DeliveryDetail deliveryDetail = new DeliveryDetail();
        deliveryDetail.setWorkitems(sWorkitems);
        deliveryDetail.setBranches(sBranches);
        deliveryDetail.setDetailList(details);
        deliveryDetail.setPatchCount(patchCount);

        return deliveryDetail;
    }

    @Override
    public void merge(Integer id) {
        SDelivery delivery = this.baseMapper.selectById(id);
        if (delivery == null) {
            throw new DeveloperException("找不到" + id + "对应投放申请");
        }
        if (!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)) {
            throw new DeveloperException("投放申请'" + delivery.getApplyAlias() + "'当前状态为" +
                    delivery.getDeliveryResult().toString() + "，只能合并申请中状态的投放申请！");
        }
        delivery.setDeliveryResult(DeliveryResult.MERGED);
        delivery.setMergeType(MergeType.MANUAL.getValue().toString());
        this.baseMapper.updateById(delivery);
    }

    @Override
    public void unmerge(String id) {
        SDelivery delivery = this.baseMapper.selectById(id);
        if (delivery == null) {
            throw new DeveloperException("找不到" + id + "对应投放申请");
        }
        if (!delivery.getDeliveryResult().equals(DeliveryResult.MERGED)) {
            throw new DeveloperException("投放申请'" + delivery.getApplyAlias() + "'当前状态为" +
                    delivery.getDeliveryResult().toString() + "，只能取消已合并状态的投放申请！");
        }
        delivery.setDeliveryResult(DeliveryResult.APPLYING);
        delivery.setMergeType(null);
        this.baseMapper.updateById(delivery);
    }

    /**
     * 判断是否允许合并投放，返回合并申请信息集合
     *
     * @param deliveryGuids
     * @return
     * @throws DeveloperException
     */
    private List<SDelivery> isAllowMerge(List<String> deliveryGuids) throws DeveloperException {
        // 查询合并清单信息
        EntityWrapper<SDelivery> deliveryWrapper = new EntityWrapper<>();
        deliveryWrapper.in(SDelivery.COLUMN_GUID, deliveryGuids);
        List<SDelivery> sDeliveries = this.baseMapper.selectList(deliveryWrapper);
        if (CollectionUtils.isEmpty(sDeliveries)) {
            throw new DeveloperException("合并的投放申请不存在！");
        }
        // 统计
        long count = sDeliveries.stream()
                .filter(d -> !d.getDeliveryResult().isSuccess()).count();
        if (count > 0) {
            throw new DeveloperException("合并的投放申请状态必须为成功！");
        }
        long profileCount = sDeliveries.stream().map(SDelivery::getGuidProfiles).distinct().count();
        if (profileCount > 1) {
            throw new DeveloperException("合并的投放申请环境必须相同！");
        }
        return sDeliveries;
    }

    @Override
    public List<String> selectDeliveryProName(String guidDelivery) {
        SDelivery delivery = selectById(guidDelivery);

        EntityWrapper<SDeliveryList> deliveryListEntityWrapper = new EntityWrapper<>();
        deliveryListEntityWrapper.eq(SDeliveryList.COLUMN_GUID_DELIVERY, delivery.getGuid());
        List<SDeliveryList> deliveryLists = deliveryListService.selectList(deliveryListEntityWrapper);
        Set<String> str = new HashSet<>();
        for (SDeliveryList deliveryList : deliveryLists) {
            str.add(deliveryList.getPartOfProject());
        }
        return new ArrayList<>(str);
    }


    @Override
    public List<SDelivery> selectAddToDelivery(Integer workitemGuid) {
        EntityWrapper<SDelivery> deliveryEntityWrapper = new EntityWrapper<>();
        deliveryEntityWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, workitemGuid);
        List<SDelivery> deliveries = selectList(deliveryEntityWrapper);
        //获取投放申请中的申请集合
        List<SDelivery> applying = deliveries.stream().filter(delis ->
                DeliveryResult.APPLYING.equals(delis.getDeliveryResult())).collect(Collectors.toList());
        if (applying.size() == 0) {
            throw new DeveloperException("没有对应的投放申请可以追加！");
        }
        //获取同一批次号的投放申请
        List<SDelivery> deliveryList = deliveries.stream().filter(delis ->
                applying.get(0).getBatchNumber().equals(delis.getBatchNumber())).collect(Collectors.toList());
        for (SDelivery delivery:deliveryList){
            if(!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)){
                throw new DeveloperException("此工作项上次投放得申请正在处理或已处理完毕，不允许追加！");
            }
        }
        return deliveryList;
    }

    @Override
    public void deleteDeliveryAndDeliveryList(Integer guidDelivery) throws SVNException {

        SDelivery delivery = selectById(guidDelivery);
        if (delivery == null) {
            throw new DeveloperException("没有找到对应的投放申请！");
        }
        if (!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)) {
            throw new DeveloperException("只能删除申请状态的投放申请！");
        }
        EntityWrapper<SDelivery> deliverysEntityWrapper = new EntityWrapper<>();
        deliverysEntityWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, delivery.getGuidWorkitem());
        deliverysEntityWrapper.eq(SDelivery.COLUMN_BATCH_NUMBER, delivery.getBatchNumber());
        List<SDelivery> deliveries = selectList(deliverysEntityWrapper);

        deliveries.forEach(deli -> {
            if(!deli.getDeliveryResult().equals(DeliveryResult.APPLYING)){
                throw new DeveloperException("与此申请同批次号的投放申请正在处理或已处理完成，不允许删除！");
            }
        });
        List<Integer> guidDeliverys = deliveries.stream().map(SDelivery::getGuid).collect(Collectors.toList());

        EntityWrapper<SDeliveryList> deliveryListEntityWrapper = new EntityWrapper<>();
        deliveryListEntityWrapper.in(SDeliveryList.COLUMN_GUID_DELIVERY, guidDeliverys);
        List<SDeliveryList> deliveryLists = deliveryListService.selectList(deliveryListEntityWrapper);
        //删除投放申请的清单列表
        if (deliveryLists.size() > 0) {
            deliveryListService.deleteBatchIds(deliveryLists.stream().map(
                    SDeliveryList::getGuid).collect(Collectors.toList()));
        }
        //删除同批次号的投放申请
        if(deliveries.size() > 0){
            deleteBatchIds(guidDeliverys);
        }
        EntityWrapper<SBranchMapping> branchMappingEntityWrapper = new EntityWrapper<>();
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_FOR_WHAT,BranchForWhat.WORKITEM);
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_GUID_OF_WHATS, delivery.getGuidWorkitem());
        List<SBranchMapping> branchMappings = branchMappingService.selectList(branchMappingEntityWrapper);
        if(branchMappings.size() > 0){
            SBranch branch = branchService.selectById(branchMappings.get(0).getGuidBranch());
            //版本号回退
            branchService.revertBranchRevision(branch.getGuid());
        }
    }

    @Override
    public SDeliveryListDetail selectDeliveryListByGuidDelivery(Integer guidDelivery) {

        SDelivery delivery = selectById(guidDelivery);
        if(delivery == null){
            throw new DeveloperException("没有guid为"+guidDelivery+"投放申请！");
        }
        //根本投放申请的工作项guid查询关联的信息
        EntityWrapper<SBranchMapping> branchMappingEntityWrapper = new EntityWrapper<>();
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_GUID_OF_WHATS, delivery.getGuidWorkitem());
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_FOR_WHAT, BranchForWhat.WORKITEM);
        List<SBranchMapping> branchMappings = branchMappingService.selectList(branchMappingEntityWrapper);
        if(branchMappings.size() == 0){
            throw new DeveloperException("没有找到此投放申请的工作项关联分支的信息！");
        }
        SBranch branch = branchService.selectById(branchMappings.get(0).getGuidBranch());
        if(branch == null){
            throw new DeveloperException("没有找到对应的分支信息！");
        }
        EntityWrapper<SDeliveryList> deliveryListEntityWrapper = new EntityWrapper<>();
        deliveryListEntityWrapper.eq(SDeliveryList.COLUMN_GUID_DELIVERY, guidDelivery);
        List<SDeliveryList> deliveryLists = deliveryListService.selectList(deliveryListEntityWrapper);
        if(deliveryLists.size() == 0){
            throw new DeveloperException("没有找到投放申请下的代码清单集合！");
        }
        List<SDeliveryList> deliveryList = new ArrayList<>();
        //截掉工程前面的分支字符
        for(SDeliveryList sdl:deliveryLists){
            sdl.setFullPath(sdl.getFullPath().substring(branch.getFullPath().length()));
            deliveryList.add(sdl);
        }
        List<DeliveryProjectDetail> deliveryProjectDetails = DeliveryProjectDetail.
                getDeliveryListDetail(deliveryLists, projectService.selectProjectAll());
        SDeliveryListDetail detail = new SDeliveryListDetail();
        detail.setCount(deliveryLists.size());
        detail.setDeliveryProjectDetails(deliveryProjectDetails);
        detail.setFullPath(branch.getFullPath());
        return detail;
    }

    @Override
    public List<SDelivery> selectDeliveryOutExecl(DeliveryOutExeclRequest request) {

        EntityWrapper<SDelivery> deliveryEntityWrapper = new EntityWrapper<>();
        deliveryEntityWrapper.eq(SDelivery.COLUMN_GUID_PROFILES, request.getGuidProfile());
        deliveryEntityWrapper.eq(SDelivery.COLUMN_PACK_TIMING, request.getPackTiming());
        deliveryEntityWrapper.eq("DATE_FORMAT(" + SDelivery.COLUMN_DELIVERY_TIME + ", '%Y-%m-%d')",
                new SimpleDateFormat("yyyy-MM-dd").format(request.getDeliveryTime()));
        deliveryEntityWrapper.eq(SDelivery.COLUMN_DELIVERY_RESULT, DeliveryResult.DELIVERED);
        List<SDelivery> deliveries = selectList(deliveryEntityWrapper);

        if (deliveries.size() == 0) {
            throw new DeveloperException("没有找到对应的投放申请！");
        }
        return deliveries;
    }

    @Override
    public void updateDelivery(SDeliveryUpdateRequest request) throws ParseException {
        SDelivery sDelivery = selectById(request.getGuidDelivery());
        if(sDelivery == null){
            throw new DeveloperException("此投放申请不存在！");
        }

        if (!sDelivery.getDeliveryResult().equals(DeliveryResult.APPLYING)) {
            throw new DeveloperException("此投放申请已成功投放，不允许删除！");
        }
        //判断投放时间及投放窗口是否合理
        Date date = new Date();
        SimpleDateFormat ymdFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat hmFormat = new SimpleDateFormat("HH:mm");
        if (ymdFormat.format(request.getDeliveryTime()).equals(ymdFormat.format(date))){
            //投放窗口的时间戳
            long time1 = hmFormat.parse(request.getPackTiming()).getTime();
            //当前时间的时间戳
            long time2 = hmFormat.parse(hmFormat.format(date)).getTime();
            if(time2 > time1){
                throw new DeveloperException("你修改投放的窗口已经过期，请选择下一个窗口投放！");
            }
        }else{
            //将投放时间转成时间戳
            long deliverTime1 = ymdFormat.parse(ymdFormat.format(request.getDeliveryTime())).getTime();
            //当前时间的时间戳
            long time2 = ymdFormat.parse(ymdFormat.format(request.getDeliveryTime())).getTime();
            if(time2 > deliverTime1){
                throw new DeveloperException("你选择的投放日期已是过去日期，请重新投放时间！");
            }
        }
        EntityWrapper<SDelivery> deliveryWrapper = new EntityWrapper<>();
        deliveryWrapper.eq(SDelivery.COLUMN_DELIVERY_RESULT,DeliveryResult.DELIVERED);
        deliveryWrapper.eq("DATE_FORMAT(" + SDelivery.COLUMN_DELIVERY_TIME + ", '%Y-%m-%d')",
                new SimpleDateFormat("yyyy-MM-dd").format(request.getDeliveryTime()));
        deliveryWrapper.eq(SDelivery.COLUMN_PACK_TIMING,request.getPackTiming());
        deliveryWrapper.eq(SDelivery.COLUMN_GUID_PROFILES,sDelivery.getGuidProfiles());
        List<SDelivery> deliveries = selectList(deliveryWrapper);
        if(deliveries.size() > 0){
            throw new DeveloperException("你选择的投放环境对应的打包窗口已完成投放，请重新选择！");
        }

        //集合添加核对中及核对成功状态，控制投放申请的环境是否可投放
        List<CheckStatus> checkStatuses = new ArrayList<>();
        checkStatuses.add(CheckStatus.WAIT);
        checkStatuses.add(CheckStatus.SUCCESS);
        //获取这个投放申请的运行环境是否有正在核对中
        EntityWrapper<SCheck> checkEntityWrapper = new EntityWrapper<>();
        checkEntityWrapper.eq(SCheck.COLUMN_GUID_PROFILES, sDelivery.getGuidProfiles());
        checkEntityWrapper.in(SCheck.COLUMN_CHECK_STATUS, checkStatuses);
        checkEntityWrapper.eq(SCheck.COLUMN_PACK_TIMING, request.getPackTiming());
        checkEntityWrapper.eq("DATE_FORMAT(" + SCheck.COLUMN_DELIVERY_TIME + ", '%Y-%m-%d')",
                new SimpleDateFormat("yyyy-MM-dd").format(request.getDeliveryTime()));
        if(checkService.selectList(checkEntityWrapper).size() > 0){
            throw new DeveloperException("你本次选择投放的环境窗口有申请正在核对中！");
        }

        sDelivery.setDeliveryTime(request.getDeliveryTime());
        sDelivery.setPackTiming(request.getPackTiming());

        updateById(sDelivery);
    }

    @Override
    public SProfileDetail selectProfileDeteilVerify(Integer guidDelivery) {
        SDelivery delivery = selectById(guidDelivery);
        if(delivery == null){
            throw new DeveloperException("查询不到对应的投放申请!");
        }
        return profileDeteilVerify(delivery.getGuidProfiles());
    }

    @Override
    public SProfileDetail profileDeteilVerify(Integer guidProfiles) {
        SProfiles sProfiles = profilesService.selectById(guidProfiles);
        if(sProfiles == null){
            throw new DeveloperException("查询不到对应的运行环境!");
        }
        EntityWrapper<SCheck> checkEntityWrapper = new EntityWrapper<>();
        checkEntityWrapper.eq(SCheck.COLUMN_GUID_PROFILES, guidProfiles);
        checkEntityWrapper.eq("DATE_FORMAT(" + SDelivery.COLUMN_DELIVERY_TIME + ", '%Y-%m-%d')",
                new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        List<SCheck> checks = checkService.selectList(checkEntityWrapper);

        SProfileDetail sProfileDetail = new SProfileDetail();
        PackTimeVerify packTimeVerify = null;
        try {
            //验证投放时间及投放窗口
            packTimeVerify = profilesService.packTimeVerify(sProfiles.getPackTiming(),checks);
        } catch (ParseException e) {
            throw new DeveloperException("窗口不是时间格式!");
        }
        if(packTimeVerify == null){
            throw new DeveloperException("找不到此投放申请运行环境的打包窗口!");
        }
        sProfileDetail.setDeliveryTime(packTimeVerify.getDeliveryTime());
        sProfileDetail.setGuidProfile(sProfiles.getGuid());
        sProfileDetail.setProfilesName(sProfiles.getProfilesName());
        sProfileDetail.setPackTimeDetails(packTimeVerify.getPackTimeDetails());

        return sProfileDetail;
    }

    @Override
    public List<SDelivery> deliveredNewProfiles(DeliveredNewProfilesRequest request) throws ParseException {
        SDelivery delivery = selectById(request.getGuidDelivery());
        if(delivery == null){
            throw new DeveloperException("找不到此投放申请!");
        }
        if(!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)){
            throw new DeveloperException("此投放申请正在处理或已被处理!");
        }
        EntityWrapper<SDelivery> deliveryEntityWrapper = new EntityWrapper<>();
        deliveryEntityWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, delivery.getGuidWorkitem());
        List<SDelivery> deliverys = selectList(deliveryEntityWrapper);

        List<Integer> guidProfile = request.getProfiles().stream().
                map(DeliveryProfileRequest::getGuidProfiles).collect(Collectors.toList());

        //过滤出以前投放的所有环境在本次也投放过的环境
        List<SDelivery> deliveries = deliverys.stream().filter(deli ->
                guidProfile.contains(delivery.getGuidProfiles())).collect(Collectors.toList());

        if(deliveries.size() > 0){
            throw new DeveloperException("不能向已投放的环境继续投放!");
        }

        //查询此投放申请的工作项是否有关联分支信息
        EntityWrapper<SBranchMapping> branchMappingEntityWrapper = new EntityWrapper<>();
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_GUID_OF_WHATS, delivery.getGuidWorkitem());
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_FOR_WHAT,BranchForWhat.WORKITEM);
        List<SBranchMapping> branchMappings = branchMappingService.selectList(branchMappingEntityWrapper);
        if(branchMappings.size() != 1){
            throw new DeveloperException("此工作项的投放申请没有关联分支信息!");
        }
        SBranch branch = branchService.selectById(branchMappings.get(0).getGuidBranch());

        //获取本次要投克隆投放申请的代码
        EntityWrapper<SDeliveryList> deliveryListEntityWrapper = new EntityWrapper<>();
        deliveryListEntityWrapper.eq(SDeliveryList.COLUMN_GUID_DELIVERY, delivery.getGuid());
        List<SDeliveryList> sDeliveryLists = deliveryListService.selectList(deliveryListEntityWrapper);
        //获取此工作项的标准清单代码
        EntityWrapper<SStandardList> standardListEntityWrapper = new EntityWrapper<>();
        standardListEntityWrapper.eq(SStandardList.COLUMN_GUID_WORKITEM, delivery.getGuidWorkitem());
        List<SStandardList> standardLists = standardListService.selectList(standardListEntityWrapper);

        SimpleDateFormat ymdFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<SDelivery> sDeliveries = new ArrayList<>();
        //根据投放的环境个数生成对应个数的投放申请
        for (DeliveryProfileRequest profiles:request.getProfiles()){
            SDelivery sDelivery = new SDelivery();
            BeanUtils.copyProperties(delivery,sDelivery);
            sDelivery.setGuid(null);
            sDelivery.setGuidProfiles(profiles.getGuidProfiles());
            sDelivery.setPackTiming(profiles.getPackTiming());
            sDelivery.setDeliveryTime(ymdFormat.parse(ymdFormat.format(profiles.getDeliveryTime())));
            sDelivery.setApplyAlias(profiles.getApplyAlias());
            sDelivery.setDeliveryResult(DeliveryResult.APPLYING);
            sDeliveries.add(sDelivery);
        }
        //新增投放申请
        if (sDeliveries.size() > 0){
            insertBatch(sDeliveries);
        }

        List<SDeliveryList> deliveryLists = new ArrayList<>();
        //判断此工作项是否有标准清单内容
        if(standardLists.size()> 0){
            for (SDelivery sDelivery : sDeliveries) {
                here:
                for (SStandardList standardList : standardLists) {
                    for (SDeliveryList sDeliveryList : sDeliveryLists) {
                        //筛选标准清单与被复制投放清单的同一个文件
                        if(standardList.getFullPath().equals(sDeliveryList.getFullPath())){
                            continue here;
                        }
                    }
                    //组装投放申请
                    SDeliveryList deliveryList = new SDeliveryList();
                    BeanUtils.copyProperties(standardList, deliveryList);
                    deliveryList.setGuid(null);
                    deliveryList.setGuidDelivery(sDelivery.getGuid());
                    deliveryList.setFromType(DeliveryListFromType.STANDARD);
                    deliveryLists.add(deliveryList);
                }
            }
            //根据投放申请生成对应的代码明细
            for (SDelivery sDelivery : sDeliveries) {
                for (SDeliveryList sDeliveryList : sDeliveryLists) {
                    SDeliveryList deliveryList = new SDeliveryList();
                    //将代码明细copy新建的代码明细对象中
                    BeanUtils.copyProperties(sDeliveryList,deliveryList);
                    for (SStandardList standardList : standardLists) {
                        //判断标准清单里是否有代码清单导出为ECD
                        if(PatchType.ECD.equals(standardList.getPatchType())){
                            //获取截取路径到模块前面的字符
                            String subPath = standardList.getFullPath().substring(
                                    0,standardList.getFullPath().indexOf(DeveloperUtils.getModule(
                                            branch.getFullPath(), standardList.getFullPath())));
                            /*
                                如果标准清单的工程模块导出为ecd，这次投放的代码清单也是标准清单模块下的文件，那么将
                                这个投放代码的导出变更标准清单的导出类型
                             */
                            if(sDeliveryList.getFullPath().contains(subPath) && PatchType.EPD.equals(sDeliveryList.getPatchType())){
                                deliveryList.setPatchType(standardList.getPatchType());
                                break ;
                            }
                        }
                    }
                    deliveryList.setGuidDelivery(sDelivery.getGuid());
                    deliveryList.setGuid(null);
                    deliveryLists.add(deliveryList);
                }
            }

        }else{
            //直接将被克隆的投放申请投入到新环境
            for (SDelivery sDelivery : sDeliveries) {
                for (SDeliveryList sDeliveryList : sDeliveryLists) {
                    SDeliveryList deliveryList = new SDeliveryList();
                    BeanUtils.copyProperties(sDeliveryList,deliveryList);
                    deliveryList.setGuid(null);
                    deliveryList.setGuidDelivery(sDelivery.getGuid());
                    deliveryLists.add(deliveryList);
                }
            }
        }
        if(deliveryLists.size() > 0){
            deliveryListService.insertBatch(deliveryLists);
        }

        return sDeliveries;
    }

    @Override
    public String selectDeliveredWay(Integer guidWorkitem) {
        //获取工作项所有的投放申请
        EntityWrapper<SDelivery> deliveryEntityWrapper = new EntityWrapper<>();
        deliveryEntityWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, guidWorkitem);
        deliveryEntityWrapper.eq(SDelivery.COLUMN_APPLY_TYPE, ApplyType.DELIVERY);
        List<SDelivery> deliveries = selectList(deliveryEntityWrapper);

        //筛选出投放申请为核对中、已合并、核对成功的申请
        List<SDelivery> delis = deliveries.stream().filter(deli ->
                DeliveryResult.CHECKING.equals(deli.getDeliveryResult()) ||
                        DeliveryResult.MERGED.equals(deli.getDeliveryResult()) ||
                        DeliveryResult.SUCCESS.equals(deli.getDeliveryResult())).collect(Collectors.toList());
        if(delis.size() > 0){
            throw new DeveloperException("你有投放申请正在处理中，不允许提交新的申请!");
        }
        //筛选此工作项所有为申请中的投放申请
        List<SDelivery> applyingDelivery = deliveries.stream().filter(deli ->
                    DeliveryResult.APPLYING.equals(deli.getDeliveryResult())).collect(Collectors.toList());
        JSONObject result = new JSONObject();
        if(applyingDelivery.size() > 0 ){
            EntityWrapper<SDelivery> batchDeliveryWrapper = new EntityWrapper<>();
            batchDeliveryWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, guidWorkitem);
            batchDeliveryWrapper.eq(SDelivery.COLUMN_BATCH_NUMBER, applyingDelivery.get(0).getBatchNumber());
            batchDeliveryWrapper.eq(SDelivery.COLUMN_APPLY_TYPE, ApplyType.DELIVERY);
            List<SDelivery> sDeliveries = selectList(batchDeliveryWrapper);
            //
            if(sDeliveries.size() == applyingDelivery.size()){
                result.put("result", DeliveredStatus.SUPER.getValue());
                return result.toString();
            }else{
                result.put("result", DeliveredStatus.FAILED.getValue());
                return result.toString();
            }
        }
        result.put("result", DeliveredStatus.DELIVERED.getValue());
        return result.toString();

    }

    @Override
    public List<SDelivery> selectApplyingDelivery(Integer guidWorkitem) {
        EntityWrapper<SDelivery> deliveryEntityWrapper = new EntityWrapper<>();
        deliveryEntityWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, guidWorkitem);
        deliveryEntityWrapper.eq(SDelivery.COLUMN_DELIVERY_RESULT, DeliveryResult.APPLYING);
        deliveryEntityWrapper.eq(SDelivery.COLUMN_APPLY_TYPE, ApplyType.DELIVERY);
        List<SDelivery> deliveries = selectList(deliveryEntityWrapper);
        //查询同一批次的所有申请
        EntityWrapper<SDelivery> deliverysEntityWrapper = new EntityWrapper<>();
        deliverysEntityWrapper.eq(SDelivery.COLUMN_GUID_WORKITEM, guidWorkitem);
        deliverysEntityWrapper.eq(SDelivery.COLUMN_BATCH_NUMBER, deliveries.get(0).getBatchNumber());
        return selectList(deliverysEntityWrapper);
    }

    @Override
    public void delievryBuyFailed(List<Integer> guidDelivery) {
        List<SDelivery> deliveries = selectBatchIds(guidDelivery);
        if(guidDelivery.size() != deliveries.size()){
            throw new DeveloperException("guid数组中有投放申请不存在!");
        }

        for (SDelivery delivery:deliveries){
            if(!deliveries.get(0).getBatchNumber().equals(delivery.getBatchNumber())){
                throw new DeveloperException("只允许将同一批次号的投放申请置为失败!");
            }
        }
        List<SDelivery> sDeliveries = deliveries.stream().filter(delivery ->
                DeliveryResult.APPLYING.equals(delivery.getDeliveryResult())).collect(Collectors.toList());

        for (SDelivery delivery:sDeliveries){
            if(!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)){
                throw new DeveloperException("要置为失败的投放申请有申请正在处理中，请关闭后重试!");
            }
            delivery.setDeliveryResult(DeliveryResult.FAILED);
        }
        updateBatchById(deliveries);
        //获取同批次的投放申请
        EntityWrapper<SDelivery> deliveryEntityWrapper = new EntityWrapper<>();
        deliveryEntityWrapper.eq(SDelivery.COLUMN_BATCH_NUMBER, deliveries.get(0).getBatchNumber());
        List<SDelivery> delivers = selectList(deliveryEntityWrapper);
        //判断同批次号的投放是否全部是申请失败，如果是，版本号回退
        List<SDelivery> deliveryCount = new ArrayList<>();
        for(SDelivery delivery:delivers){
            if(!DeliveryResult.FAILED.equals(delivery.getDeliveryResult())){
                deliveryCount.add(delivery);
            }
        }
        EntityWrapper<SBranchMapping> branchMappingEntityWrapper = new EntityWrapper<>();
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_FOR_WHAT, BranchForWhat.WORKITEM);
        branchMappingEntityWrapper.eq(SBranchMapping.COLUMN_GUID_OF_WHATS, delivers.get(0).getGuidWorkitem());
        List<SBranchMapping> branchMappings = branchMappingService.selectList(branchMappingEntityWrapper);

        if(deliveryCount.size() == 0){
            branchService.revertBranchRevision(branchMappings.get(0).getGuidBranch());
        }
    }

    @Override
    public List<DeliveryResultCountDetail> selectDeliveryResultGroupCount() {

        List<DeliveryResultCountDetail> deliveryResultCountDetails = this.baseMapper.selectDeliveryResultGroupCount();
        //continue here:循环标志
        here:
        for (DeliveryResult deliveryResult:DeliveryResult.values()){
            for (DeliveryResultCountDetail resultCountDetail:deliveryResultCountDetails){
                if(resultCountDetail.getDeliveryResult().equals(deliveryResult.getValue())){
                    continue here;
                }
            }
            DeliveryResultCountDetail resultCountDetail = new DeliveryResultCountDetail();
            resultCountDetail.setCount(0);
            resultCountDetail.setDeliveryResult(deliveryResult.getValue().toString());
            deliveryResultCountDetails.add(resultCountDetail);
        }
        return deliveryResultCountDetails;
    }

    @Override
    public void dislodgeDelivery(Integer guidDelivery) {

        SDelivery delivery = selectById(guidDelivery);
        if(delivery == null){
            throw new DeveloperException("此申请不存在!");
        }
        if(!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)){
            throw new DeveloperException("此申请状态不为申请中，不允许置失败!");
        }
        SDelivery sDelivery = new SDelivery();
        sDelivery.setGuid(delivery.getGuid());
        sDelivery.setDeliveryResult(DeliveryResult.FAILED);
        updateById(sDelivery);
    }

    @Override
    public MergeReportDetail forecastMerge(Integer guidDelivery, boolean real) throws SVNException {
        SDelivery delivery = selectById(guidDelivery);
        if(delivery == null){
            throw new DeveloperException("此guid为"+guidDelivery+"申请不存在!");
        }
        if (!delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)){
            throw new DeveloperException("此申请的状态不为申请中，请选择申请中的申请进行合并!");
        }
        //查询此申请的合并报告
        EntityWrapper<SMergeReport> mergeReportEntityWrapper = new EntityWrapper<>();
        mergeReportEntityWrapper.eq(SMergeReport.COLUMN_GUID_DELIVERY, guidDelivery);
        List<SMergeReport> mergeReports = mergeReportService.selectList(mergeReportEntityWrapper);
        if (mergeReports.size() > 0){
            //查询合并报告明细
            EntityWrapper<SMergeReportList> mergeReportListEntityWrapper = new EntityWrapper<>();
            mergeReportListEntityWrapper.eq(SMergeReportList.COLUMN_GUID_MERGE_REPORT, mergeReports.get(0).getGuid());
            List<SMergeReportList> mergeReportLists = mergeReportListService.selectList(mergeReportListEntityWrapper);
            //组装返回格式
            List<MergeReportListDetail> mergeReportListDetails = new ArrayList<>();
            mergeReportLists.forEach(mergeReportList ->{
                MergeReportListDetail mergeReportListDetail = new MergeReportListDetail();
                BeanUtils.copyProperties(mergeReportList, mergeReportListDetail);
                mergeReportListDetail.setWhoChangedConflictDetails(new ArrayList<>());
                mergeReportListDetails.add(mergeReportListDetail);
            });
            //组织返回报告格式
            MergeReportDetail mergeReportDetail1 = new MergeReportDetail();
            BeanUtils.copyProperties(mergeReports.get(0), mergeReportDetail1);
            mergeReportDetail1.setRealMerge(true);
            mergeReportDetail1.setConflictReportDetails(mergeReportListDetails);
            //确认合并状态
            merge(delivery.getGuid());
            return mergeReportDetail1;
        }

        EntityWrapper<SDeliveryList> deliveryListEntityWrapper = new EntityWrapper<>();
        deliveryListEntityWrapper.eq(SDeliveryList.COLUMN_GUID_DELIVERY, guidDelivery);
        List<SDeliveryList> deliveryLists = deliveryListService.selectList(deliveryListEntityWrapper);
        if (deliveryLists.isEmpty()){
            throw new DeveloperException("此申请没有代码记录!");
        }
        //获取运行环境
        SProfiles profiles = profilesService.selectById(delivery.getGuidProfiles());
        if (profiles == null){
            throw new DeveloperException("找不到guid为" +delivery.getGuidProfiles()+ "的运行环境信息!");
        }
        EntityWrapper<SBranchMapping> branchMappingProfiles = new EntityWrapper<>();
        branchMappingProfiles.eq(SBranchMapping.COLUMN_GUID_OF_WHATS, profiles.getGuid())
                .eq(SBranchMapping.COLUMN_FOR_WHAT, BranchForWhat.RELEASE);
        List<SBranchMapping> profilesBranchMappings = branchMappingService.selectList(branchMappingProfiles);
        if (profilesBranchMappings.isEmpty()){
            throw new DeveloperException("找不到guid为" +delivery.getGuidProfiles()+ "运行环境对应的分支信息!");
        }
        //获取运行环境的分支信息
        SBranch profilesBranch = branchService.selectById(profilesBranchMappings.get(0).getGuidBranch());

        //获取工作项信息
        SWorkitem workitem = workitemService.selectById(delivery.getGuidWorkitem());
        if (workitem == null){
            throw new DeveloperException("找不到guid为" +delivery.getGuidProfiles()+ "的工作项信息!");
        }
        EntityWrapper<SBranchMapping> branchMappingWorkitem = new EntityWrapper<>();
        branchMappingWorkitem.eq(SBranchMapping.COLUMN_GUID_OF_WHATS, workitem.getGuid())
                .eq(SBranchMapping.COLUMN_FOR_WHAT, BranchForWhat.WORKITEM);
        List<SBranchMapping> workitemBranchMappings = branchMappingService.selectList(branchMappingWorkitem);
        if (workitemBranchMappings.isEmpty()){
            throw new DeveloperException("找不到guid为" +delivery.getGuidProfiles()+ "运行环境对应的分支信息!");
        }
        //获取工作项的分支信息
        SBranch workitemBranch = branchService.selectById(workitemBranchMappings.get(0).getGuidBranch());
        MergeReportDetail mergeReportDetail = null;
        //调用合并接口
        if (real){
            //真合并
            mergeReportDetail = svnKitService.realMerge(profiles, profilesBranch.getFullPath(), workitem,
                                        workitemBranch.getFullPath(), delivery, deliveryLists);
            if (mergeReportDetail.isRealMerge()){
                //确认合并状态
                delivery.setDeliveryResult(DeliveryResult.MERGED);
                delivery.setMergeType(MergeType.AUTOMATIC.getValue().toString());
                this.baseMapper.updateById(delivery);
            }
        }else{
            //预合并
            mergeReportDetail = svnKitService.beforehandMerge(profiles, profilesBranch.getFullPath(), workitem,
                                        workitemBranch.getFullPath(), delivery, deliveryLists);
        }
        return mergeReportDetail;
    }

    @Override
    public MergeReportDetail selectMergeReport(Integer guidDelivery) {
        SDelivery delivery = selectById(guidDelivery);
        if(delivery == null){
            throw new DeveloperException("此guid为"+guidDelivery+"申请不存在!");
        }
        if (delivery.getDeliveryResult().equals(DeliveryResult.APPLYING)){
            throw new DeveloperException("此申请的状态为申请中，没有合并报告!");
        }
        //查询此申请的合并报告
        EntityWrapper<SMergeReport> mergeReportEntityWrapper = new EntityWrapper<>();
        mergeReportEntityWrapper.eq(SMergeReport.COLUMN_GUID_DELIVERY, guidDelivery);
        List<SMergeReport> mergeReports = mergeReportService.selectList(mergeReportEntityWrapper);
        if (mergeReports.size() == 0){
            throw new DeveloperException("此申请没有合并报告!");
        }
        //查询合并报告明细
        EntityWrapper<SMergeReportList> mergeReportListEntityWrapper = new EntityWrapper<>();
        mergeReportListEntityWrapper.eq(SMergeReportList.COLUMN_GUID_MERGE_REPORT, mergeReports.get(0).getGuid());
        List<SMergeReportList> mergeReportLists = mergeReportListService.selectList(mergeReportListEntityWrapper);
        //组装返回格式
        List<MergeReportListDetail> mergeReportListDetails = new ArrayList<>();
        mergeReportLists.forEach(mergeReportList ->{
            MergeReportListDetail mergeReportListDetail = new MergeReportListDetail();
            BeanUtils.copyProperties(mergeReportList, mergeReportListDetail);
            mergeReportListDetail.setWhoChangedConflictDetails(new ArrayList<>());
            mergeReportListDetails.add(mergeReportListDetail);
        });
        //组织返回报告格式
        MergeReportDetail mergeReportDetail1 = new MergeReportDetail();
        BeanUtils.copyProperties(mergeReports.get(0), mergeReportDetail1);
        mergeReportDetail1.setRealMerge(true);
        mergeReportDetail1.setConflictReportDetails(mergeReportListDetails);
        return mergeReportDetail1;
    }

}

